/*
 * @Author: hrg
 * @Date: 2023-05-20 17:57:00
 * @LastEditTime: 2023-05-22 15:17:32
 * @FilePath: \study_go\study05\demo_接口定义及接口的注意事项\main\main.go
 * @Description:接口及接口的注意事项
 */
package main

/*
	接口的总结：
		- 接口中可以定义一组方法，但不需要实现，不需要方法体。并且接口中不能包含任何变量。
			到某个自定义类型要是用的时候（实现接口的时候）再根据具体情况把这些方法具体实现出来。
		-实现接口要实现所有的方法才是实现。
		-golang中的接口不需要显示的实现接口，golang中没有implement关键字
			（golang中实现接口是基于方法的，不是基于接口的）
			例如：
				A接口：a,b方法
				B接口：a,b方法
				C结构体实现了a,b方法，那么C实现了A接口，也可以说实现了B接口
		-接口的目的：
			为了定义规范，具体有别人来实现即可

	接口的注意事项：
		-接口本身不能创建实例，但是可以指向一个实现了该接口的自定义类型的变量
		-只要是自定义的数据类型，就可以实现接口，不仅仅局限于结构体类型
		-一个自定义类型可以实现多个接口
		- 一个接口(例如a接口)可以继承多个别的接口（比如b，c接口），这时，如果要实现a接口，就必须将b，c接口的方法全部实现
		- interface 类型默认是一个指针（引用类型），如果没有对interface初始化就使用，就会输出nil
		- 空接口没有任何方法，所以可以理解为所有类型都实现了空接口，也可以理解为我们可以把任意一个变量赋给空接口
*/

import "fmt"

//接口的定义：定义规则，定义规范，定义某种能力
// 定义一个接口：
type SayHello interface {
	//声明没有实现的方法
	sayHello()
}

//定义中国人：
type Chinese struct {
}

// 结构的具体实现：
func (c *Chinese) sayHello() {
	fmt.Println("你好啊？")
}

// 定义美国人
type American struct {
}

func (a *American) sayHello() {
	fmt.Println("hi")
}

// 定义一个函数，专门实现打招呼：
func greet(s SayHello) {
	s.sayHello()
}
func main() {
	// 定义结构体实例：
	c := Chinese{}

	a := American{}
	// fmt.Println(c)
	// fmt.Println(a)
	greet(&c)
	greet(&a)
}
